// package: rewords-server-2024
// filename: bcz_ctrl
// author: diogoxiang@gmail.com
// time: 2024/11/29 16:30

package bczCtrl

import (
	"context"
	"rewords-server-2024/internal/model/input/form"
	"rewords-server-2024/utility/ufun"
	"rewords-server-2024/utility/ztime"

	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"go.mongodb.org/mongo-driver/bson"

	"rewords-server-2024/api/bczAPI"
	"rewords-server-2024/internal/consts"
	"rewords-server-2024/internal/library/ecode"
	"rewords-server-2024/internal/model/entity"
	"rewords-server-2024/internal/model/input/query_in"
	"rewords-server-2024/internal/service"
)

var BczWord = new(cBczWord)

type cBczWord struct{}

// Add 添加词汇
func (c *cBczWord) Add(ctx context.Context, req *bczAPI.BaseAddReq) (res *bczAPI.BaseAddRes, err error) {
	// 构建文档
	doc := &entity.BczWord{
		Word:           req.Word,
		Accent:         req.Accent,
		MeanCn:         req.MeanCn,
		MeanEn:         req.MeanEn,
		Sentence:       req.Sentence,
		SentenceTrans:  req.SentenceTrans,
		SentencePhrase: req.SentencePhrase,
		WordEtyma:      req.WordEtyma,
		ClozeData:      req.ClozeData,
	}
	// 插入数据
	err = service.Mgx().InsertOne(ctx, consts.CBczWords, doc)
	if err != nil {
		g.Log().Error(ctx, "Insert error:", err)
		return nil, gerror.NewCode(ecode.InvalidParams)
	}

	return &bczAPI.BaseAddRes{Id: doc.Word}, nil
}

// QueryList 查询词汇列表
func (c *cBczWord) QueryList(ctx context.Context, req *bczAPI.BaseListReq) (res *bczAPI.BaseListRes, err error) {

	query, skip, limit, sort, _ := query_in.BuildMongoQueryWithPage(req.Conditions, req.OrderFields, req.Page, nil)
	g.Log().Debug(ctx, "MongoDB query conditions:", query)
	g.Log().Debug(ctx, "Skip:", skip, "Limit:", limit)

	// 查询数据
	result, err := service.Mgx().Find(ctx, consts.CBczWords, query, nil, skip, limit, sort)
	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}

	var data []entity.BczWord
	if err = gconv.Struct(result, &data); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	var total int64
	if req.Page.QueryCount {
		total, err = service.Mgx().CountDocuments(ctx, consts.CBczWords, query)
		if err != nil {
			return nil, gerror.Wrap(err, "获取总数失败")
		}
	}

	return &bczAPI.BaseListRes{
		List: ufun.If(len(data) > 0, data, []entity.BczWord{}),
		PageResult: query_in.PageResult{
			Current:  (skip / limit) + 1,
			PageSize: limit,
			Total:    total,
			Pages:    (total + limit - 1) / limit,
			HasNext:  (skip + limit) < total,
		},
	}, nil
}

// QueryInfo 查询词汇信息
func (c *cBczWord) QueryInfo(ctx context.Context, req *bczAPI.BaseInfoReq) (res *bczAPI.BaseInfoRes, err error) {
	query := bson.M{"word": req.Q}
	result, err := service.Mgx().FindOne(ctx, consts.CBczWords, query, bson.M{})
	if err != nil {
		return nil, gerror.Wrap(err, "获取数据失败")
	}

	var data entity.BczWord
	if err = gconv.Struct(result, &data); err != nil {
		return nil, gerror.Wrap(err, "数据转换失败")
	}

	return &bczAPI.BaseInfoRes{
		BczWord: data,
	}, nil
}

// Update 更新词汇
func (c *cBczWord) Update(ctx context.Context, req *bczAPI.BaseUpdateReq) (res *bczAPI.BaseUpdateRes, err error) {
	query := bson.M{"word": req.Word}
	update := bson.M{
		"$set": req.BczWord,
	}
	_, err = service.Mgx().UpdateOne(ctx, consts.CBczWords, query, update)
	if err != nil {
		return nil, gerror.Wrap(err, "更新数据失败")
	}

	return &bczAPI.BaseUpdateRes{}, nil
}

// Delete 删除词汇
func (c *cBczWord) Delete(ctx context.Context, req *bczAPI.BaseDeleteReq) (res *bczAPI.BaseDeleteRes, err error) {
	//query := bson.M{"word": req.Id}

	updateDoc := form.NewBuilder().
		//SetIfNotEmpty("status", status).
		Set("updated_at", ztime.GetLocalTime()).
		Build()
	_, err = service.Mgx().UpdateOne(ctx, consts.CBczWords,
		bson.M{
			"word": req.Id,
		},
		bson.M{
			"$set": updateDoc,
		},
	)
	if err != nil {
		return nil, gerror.Wrap(err, "删除数据失败")
	}

	return &bczAPI.BaseDeleteRes{}, nil
}
